package net.hn.hnms.biz.equipment.group.server.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import net.hn.hnms.biz.equipment.company.service.CompanyServer;
import net.hn.hnms.biz.equipment.domain.dto.EquipmentStartDayDto;
import net.hn.hnms.biz.equipment.domain.vo.EquipmentSwitchVo;
import net.hn.hnms.biz.equipment.group.domain.MineALlSwitchVo;
import net.hn.hnms.biz.equipment.group.server.GroupServer;
import net.hn.hnms.biz.equipment.mapper.EquipmentStartDayMapper;
import net.hn.hnms.biz.equipment.mapper.EquipmentStartDetailsDayMapper;
import net.hn.hnms.biz.equipment.service.EquipmentService;
import net.hn.hnms.sys.common.core.constant.Constants;
import net.hn.hnms.sys.common.core.exception.HuaNengException;
import net.hn.hnms.sys.common.core.utils.StringUtils;
import net.hn.hnms.sys.common.redis.domain.SysOrganizationVo;
import net.hn.hnms.sys.common.redis.utils.RedisUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class GroupServerImpl implements GroupServer {
    /**
     * 重大设备开机起始Mapper
     */
    @Resource
    private EquipmentStartDayMapper equipmentStartDayMapper;
    /**
     * 重大设备开机起始区间Mapper
     */
    @Resource
    private EquipmentStartDetailsDayMapper equipmentStartDetailsDayMapper;

    /**
     * 公司服务接口
     */
    @Resource
    private CompanyServer companyServer;

    /**
     * 重大设备服务接口
     */
    @Resource
    private EquipmentService equipmentService;


    /**
     * 生产看板-本月开机率台账
     *
     * @return
     */
    @Override
    //设备开机率计算公式： （设备实际工作时间/总可工作时间）*100%
    public Map operationRate(String companyCode,Date month) {
        Map<String,Object> map = new HashMap<>();

        //判断传参日期是否为空，为空则默认使用当前时间
        //获取当月的开始日期
        DateTime startTime = null;
        //获取当月的结束日期
        DateTime endTime = null;
        if (month == null) {
            //获取当月的开始日期
            startTime = DateUtil.beginOfMonth(new Date());
            //获取当月的结束日期
            endTime = DateUtil.endOfMonth(new Date());

        } else {
            startTime = DateUtil.beginOfMonth(month);
            //获取当月的结束日期
            endTime = DateUtil.endOfMonth(month);
        }
        //获取当月的间隔，单位天数
//        Long offSet = DateUtil.betweenDay(startTime, endTime, true);

        //获取公司下所有煤矿
        SysOrganizationVo sysOrganizationVos = RedisUtils.getCacheObject(Constants.SYS_CODESUB_KEY+companyCode);
        if (sysOrganizationVos == null) {
            new HuaNengException(Constants.FAIL, "未查询到该公司编码" + companyCode);
        }

        //获取当前公司的所有子煤矿

        //Y轴方向
        // 综采系统
        //综掘系统
        //主煤流系统
        //主提升系统
        //主通风系统
        //主压风系统
        //供电系统
        //主排水系统
        List<String> listY = new ArrayList<>();
        listY.add("综采系统");
        listY.add("综掘系统");
        listY.add("主煤流系统");
        listY.add("主提升系统");
        listY.add("主通风系统");
        listY.add("主压风系统");
        listY.add("主排水系统");
        listY.add("供电系统");

        for (SysOrganizationVo sysOrganizationVo : sysOrganizationVos.getSubCodeList()) {
            //煤矿编码
            String mineCode = sysOrganizationVo.getOrgCode();
            //煤矿名称
            String mineName = sysOrganizationVo.getOrgName().trim();

            List<EquipmentStartDayDto> equipmentStartDayDtoList = equipmentStartDetailsDayMapper.groupOperationRate(startTime,endTime,mineCode);
            //获取当前煤矿的所有子系统  以子系统进行分组，
            ///**
            //     * 重大设备分类，
            //     * 0代表采煤机，
            //     * 1代表掘进机，
            //     * 2代表皮带运输，
            //     * 3代表斜井提升，
            //     * 4代表主通风机
            //     * 5代表压风机，
            //     * 6代表主排水
            //     */7供电


            //当前煤矿的子系统月开机率
            List<String> listX = new ArrayList<>();
            //1割煤机开机率
            BigDecimal coalCutterValue = new BigDecimal(0);
            //2掘进机开机率
            BigDecimal tunnelBorerValue = new BigDecimal(0);
            //3煤流皮带运输开机率
            BigDecimal beltConveyorValue = new BigDecimal(0);
            //4斜井提升开机率
            BigDecimal inclineShaftValue = new BigDecimal(0);
            //5主通风机开机率
            BigDecimal ventilatorValue = new BigDecimal(0);
            //6压风机开机率
            BigDecimal compressorValue = new BigDecimal(0);
            //7主排水泵开机率
            BigDecimal pumpValue = new BigDecimal(0);
            //制氮开机率
//            BigDecimal nitrogenValue =  null;
            //8供电系统
            BigDecimal powerValue = new BigDecimal(0);
            //车辆定位
            BigDecimal carValue = new BigDecimal(0);
            //无人驾驶
            BigDecimal unmannedValue = new BigDecimal(0);

            //从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量  添加中间变量解决final问题
            List<BigDecimal> temp = new ArrayList<>();
//            temp.set(0, coalCutterValue);
//            temp.set(1, tunnelBorerValue);
//            temp.set(2, beltConveyorValue);
//            temp.set(3, inclineShaftValue);
//            temp.set(4, ventilatorValue);
//            temp.set(5, compressorValue);
//            temp.set(6, pumpValue);
//            temp.set(7, powerValue);
//            temp.set(8, carValue);
//            temp.set(9, unmannedValue);
            temp.add(0, coalCutterValue);
            temp.add(1, tunnelBorerValue);
            temp.add(2, beltConveyorValue);
            temp.add(3, inclineShaftValue);
            temp.add(4, ventilatorValue);
            temp.add(5, compressorValue);
            temp.add(6, pumpValue);
            temp.add(7, powerValue);
            temp.add(8, carValue);
            temp.add(9, unmannedValue);

            Map<Integer, List<EquipmentStartDayDto>> collect = equipmentStartDayDtoList.stream()
                    .collect(Collectors.groupingBy(EquipmentStartDayDto::getEquipmentFlag));
            collect.forEach((t,v)->{
                //遍历所有子系统 t  0代表采煤机，1代表掘进机， 2代表皮带运输，3代表斜井提升，4代表主通风机 5代表压风机，6代表主排水
                if (0 == t) {
                    BigDecimal coalCutterBigDecimal = new BigDecimal(0);
                    //采煤机
                    for (EquipmentStartDayDto equipmentStartDayDto : v) {
                        //默认情况下当前子系统的所有设备开机时间进行相加
                        coalCutterBigDecimal=coalCutterBigDecimal.add(new BigDecimal(equipmentStartDayDto.getRate()));
                    }
                    //coalCutterBigDecimal 当前子系统所有的设备月开机率之和
                    //保留三位小数，多余的删除
                    temp.set(0,coalCutterBigDecimal.setScale(3, BigDecimal.ROUND_DOWN));
                }else if (1 == t) {
                    //掘进机
                    BigDecimal tunnelBorerBigDecimal = new BigDecimal(0);
                    for (EquipmentStartDayDto equipmentStartDayDto : v) {
                        tunnelBorerBigDecimal=tunnelBorerBigDecimal.add(new BigDecimal(equipmentStartDayDto.getRate()));
                    }
                    //封装掘进机
                    temp.set(1, tunnelBorerValue.add(tunnelBorerBigDecimal.setScale(3, BigDecimal.ROUND_DOWN)));
                } else if (2 == t) {
                    //煤流皮带
                    BigDecimal beltConveyorBigDecimal = new BigDecimal(0);
                    for (EquipmentStartDayDto equipmentStartDayDto : v) {
                        beltConveyorBigDecimal=beltConveyorBigDecimal.add(new BigDecimal(equipmentStartDayDto.getRate()));
                    }
                    //封装煤流皮带
                    temp.set(2, beltConveyorValue.add(beltConveyorBigDecimal.setScale(3, BigDecimal.ROUND_DOWN)));
                } else if (3 == t) {
                    //斜井提升
                    BigDecimal inclineShaftValueBigDecimal = new BigDecimal(0);
                    for (EquipmentStartDayDto equipmentStartDayDto : v) {
                        inclineShaftValueBigDecimal=inclineShaftValueBigDecimal.add(new BigDecimal(equipmentStartDayDto.getRate()));
                    }
                    //封装斜井提升
                    temp.set(3, inclineShaftValue.add(inclineShaftValueBigDecimal.setScale(3, BigDecimal.ROUND_DOWN)));

                } else if (4 == t) {
                    //主通风机
                    BigDecimal ventilatorValueBigDecimal = new BigDecimal(0);
                    for (EquipmentStartDayDto equipmentStartDayDto : v) {
                        ventilatorValueBigDecimal=ventilatorValueBigDecimal.add(new BigDecimal(equipmentStartDayDto.getRate()));
                    }
                    //封装主通风机
                    temp.set(4, ventilatorValue.add(ventilatorValueBigDecimal.setScale(3, BigDecimal.ROUND_DOWN)));

                } else if (5 == t) {
                    //压风机
                    BigDecimal compressorValueBigDecimal = new BigDecimal(0);
                    for (EquipmentStartDayDto equipmentStartDayDto : v) {
                        compressorValueBigDecimal=compressorValueBigDecimal.add(new BigDecimal(equipmentStartDayDto.getRate()));
                    }
                    //封装压风机
                    temp.set(5, compressorValue.add(compressorValueBigDecimal.setScale(3, BigDecimal.ROUND_DOWN)));

                } else if (6 == t) {
                    //主排水
                    BigDecimal pumpValueBigDecimal = new BigDecimal(0);
                    for (EquipmentStartDayDto equipmentStartDayDto : v) {
                        pumpValueBigDecimal=pumpValueBigDecimal.add(new BigDecimal(equipmentStartDayDto.getRate()));
                    }
                    //封装主排水
                    temp.set(6, pumpValue.add(pumpValueBigDecimal.setScale(3, BigDecimal.ROUND_DOWN)));
                }//TODO 需要补充供电,车辆定位,无人驾驶

            });
            //1割煤机开机率
//            listX.add(String.valueOf(coalCutterValue));
            listX.add(String.valueOf(temp.get(0)));
            //2掘进机开机率
//            listX.add(String.valueOf(tunnelBorerValue));
            listX.add(String.valueOf(temp.get(1)));

            //3煤流皮带运输开机率
//            listX.add(String.valueOf(beltConveyorValue));
            listX.add(String.valueOf(temp.get(2)));
            //4斜井提升开机率
//            listX.add(String.valueOf(inclineShaftValue));
            listX.add(String.valueOf(temp.get(3)));
            //5主通风机开机率
//            listX.add(String.valueOf(ventilatorValue));
            listX.add(String.valueOf(temp.get(4)));
            //6压风机开机率
//            listX.add(String.valueOf(compressorValue));
            listX.add(String.valueOf(temp.get(5)));
            //7主排水泵开机率
//            listX.add(String.valueOf(pumpValue));
            listX.add(String.valueOf(temp.get(6)));
            //制氮开机率
//            BigDecimal nitrogenValue =  null;
//            listX.add(String.valueOf(nitrogenValue));
            //8供电系统
//            listX.add(String.valueOf(powerValue));
            listX.add(String.valueOf(temp.get(7)));
            //需要判断公司是否是北能,如果是北能需要做特殊处理, 新增两个系统
            if ("91150000756668318G".equals(companyCode)) {
//                listX.add(String.valueOf(carValue));
                listX.add(String.valueOf(temp.get(8)));
//                listX.add(String.valueOf(unmannedValue));
                listX.add(String.valueOf(temp.get(9)));
            }

            //区分null和0
            // if是0则置为null,如果是0.00 则不处理
            for (int j=0; j<listX.size();j++ ) {
                if ("0".equals(listX.get(j))) {
                    listX.set(j, null);
                }
            }

            //煤矿编码  当前煤矿系统的开机率数组
//            map.put(mineCode, Collections.singletonList(listX));
            //煤矿名称  当前煤矿系统的开机率数组
            map.put(mineName, listX);
        }
        //如何是北能则新增两个系统
        if ("91150000756668318G".equals(companyCode)) {
            listY.add("车辆定位");
            listY.add("无人驾驶");
        }
        map.put("listY", listY);
        return map;
    }

    /**
     * 获取所有煤矿重大设备开关信息
     * @param companyCode
     * @return
     */
    @Override
    public List<MineALlSwitchVo> getAllMineSwitch(String companyCode) {
        List<MineALlSwitchVo> voList = new ArrayList<>();
        if (StringUtils.isNotBlank(companyCode)) {
            //查询当前公司下面的所有煤矿
            //获取当前公司的所有煤矿
            SysOrganizationVo sysOrganizationVo = RedisUtils.getCacheObject(Constants.SYS_CODESUB_KEY + companyCode);

            for (SysOrganizationVo organizationVo : sysOrganizationVo.getSubCodeList()) {
                String orgCode = organizationVo.getOrgCode();
                String orgName = organizationVo.getOrgName();
                MineALlSwitchVo mineALlSwitchVo = new MineALlSwitchVo();
                mineALlSwitchVo.setMineCode(orgCode);
                mineALlSwitchVo.setMineName(orgName);
                List<EquipmentSwitchVo> equipmentSwitchVos = equipmentService.equipmentSwitchByMineCode(orgCode);
                mineALlSwitchVo.setEquipmentSwitchVo(equipmentSwitchVos);
                voList.add(mineALlSwitchVo);
            }
        } else {
            //获取集团所有煤矿
            SysOrganizationVo sysOrganizationVo = RedisUtils.getCacheObject(Constants.SYS_CODESUB_KEY + 0);
            for (SysOrganizationVo organizationVo : sysOrganizationVo.getSubCodeList()) {
                for (SysOrganizationVo vo : organizationVo.getSubCodeList()) {
                    String orgCode = vo.getOrgCode();
                    String orgName = vo.getOrgName();
                    MineALlSwitchVo mineALlSwitchVo = new MineALlSwitchVo();
                    mineALlSwitchVo.setMineCode(orgCode);
                    mineALlSwitchVo.setMineName(orgName);
                    List<EquipmentSwitchVo> equipmentSwitchVos = equipmentService.equipmentSwitchByMineCode(orgCode);
                    mineALlSwitchVo.setEquipmentSwitchVo(equipmentSwitchVos);
                    voList.add(mineALlSwitchVo);
                }
            }
        }
        return voList;
    }


}
